'''
Created on Jul 15, 2010

@author: adolfo

Unit test suite for the implementation of SMSGateway for Kannel.
'''

from ..sms_gateway import Message, SMSListener
from sms_gateway_test import MessageRecordingListener
from sms_gateway_test_application_context import KannelSMSGatewayTestConfig
from springpython.context import ApplicationContext
import logging
import unittest
import urllib

_LOGGER = logging.getLogger("mx.org.came.tests.kannel_sms_gateway_test")


class KannelSMSGatewayTest(unittest.TestCase):
    """Class that defines tests for the methods in the module
    `kannel_sms_gateway`"""

    CONTEXT = ApplicationContext(KannelSMSGatewayTestConfig())
    """Spring application context with the objects to be used in the
    unit test suite.
    """

    def setUp(self):
        """Does nothing."""
        pass
    
    def tearDown(self):
        """Does nothing"""
        pass

    def test_init(self):
        """Tests that the initialization parameters are being handled properly
        """
        # Check that the default values are being properly initialized
        kannel_gateway = KannelSMSGatewayTest.CONTEXT.get_object("default_kannel_sms_gateway")
        self.assertEquals(kannel_gateway._listeners, []
                          , "The list of listeners was not initialized to the empty list.")
        self.assertTrue(kannel_gateway._notification_server.server_name in ["localhost", "localhost.localdomain"]
                          , "The notification server address was not initialized to 'localhost.localdomain'.")
        self.assertEquals(kannel_gateway._notification_server.server_port, 55555
                          , "The notification server port was not initialized to 55555.")
        self.assertEquals(kannel_gateway._kannel_server_address, "127.0.0.1"
                          , "Kannel's server address was not initialized to '127.0.0.1'")
        self.assertEquals(kannel_gateway._kannel_server_port, 13013
                          , "Kannel's server port was not initialized to 13013")
        self.assertEquals(kannel_gateway._kannel_user, "kanneluser"
                          , "Kannel's user name was not initialized to 'kanneluser'")
        self.assertEquals(kannel_gateway._kannel_password, "kanneluser"
                          , "Kannel's password was not initialized to 'kanneluser'")
        self.assertEquals(kannel_gateway._kannel_phone_number, 1234
                          , "Kannel's phone number was not initialized to 1234")
        self.assertEquals(kannel_gateway._kannel_parameters
                          , [Message.SENDER_PHONE_NUMBER
                             , Message.UDH
                             , Message.ORIGINAL_BINARY_MESSAGE
                             , Message.RECEIVER_PHONE_NUMBER]
                          , "Kannel's URL parameters were not properly initialized.")
        # Check that the values in the test application context were correctly initialized
        kannel_gateway = KannelSMSGatewayTest.CONTEXT.get_object("kannel_sms_gateway")
        self.assertEquals(kannel_gateway._listeners, []
                          , "The list of listeners was not initialized to the empty list.")
        self.assertTrue(kannel_gateway._notification_server.server_name in ["localhost", "localhost.localdomain"]
                          , "The notification server address was not initialized to 'localhost.localdomain'.")
        self.assertEquals(kannel_gateway._notification_server.server_port, 55055
                          , "The notification server port not initialized to 55055.")
        self.assertEquals(kannel_gateway._kannel_server_address, "kannel.example.org"
                          , "Kannel's server address was not initialized to 'kannel.example.org'")
        self.assertEquals(kannel_gateway._kannel_server_port, 13131
                          , "Kannel's server port was not initialized to 13013")
        self.assertEquals(kannel_gateway._kannel_user, "user"
                          , "Kannel's user name was not initialized to 'user'")
        self.assertEquals(kannel_gateway._kannel_password, "password"
                          , "Kannel's password was not initialized to 'password'")
        self.assertEquals(kannel_gateway._kannel_phone_number, 2381280891
                          , "Kannel's phone number was not initialized to 2381280891")
        self.assertEquals(kannel_gateway._kannel_parameters
                          , [Message.SENDER_PHONE_NUMBER
                             , Message.UDH
                             , Message.ORIGINAL_BINARY_MESSAGE]
                          , "Kannel's URL parameters were not properly initialized.")
        
    def test_get_phone_number(self):
        """Verifies that get_phone_number() returns the value it was 
        initialized to.
        """
        kannel_gateway = KannelSMSGatewayTest.CONTEXT.get_object("kannel_sms_gateway")
        self.assertEquals(kannel_gateway.get_phone_number(), 2381280891
                          , "get_phone_number() did not return the expected value")
    
    def test_add_sms_listener(self):
        """Verifies that add_sms_listener(listener) actually adds a listener to
        the list.
        """
        kannel_gateway = KannelSMSGatewayTest.CONTEXT.get_object("kannel_sms_gateway")
        sms_listener = SMSListener()
        kannel_gateway.add_sms_listener(sms_listener)
        self.assertTrue(sms_listener in kannel_gateway._listeners
                          , "add_sms_listener() did not register the listener")
        kannel_gateway.remove_sms_listener(sms_listener)
        self.assertTrue(sms_listener not in kannel_gateway._listeners
                          , "remove_sms_listener() did not remove the listener.")

    def test_notify_message_reception(self):
        """Verifies that registered listeners are notified by _notify_message_reception()."""
        kannel_gateway = KannelSMSGatewayTest.CONTEXT.get_object("kannel_sms_gateway")
        listener = MessageRecordingListener()
        kannel_gateway.add_sms_listener(listener)
        # Check notification of a text message
        kannel_gateway._notify_message_reception("/2381280921&&Hello+world")
        self.assertEquals(len(listener.received_messages), 1
                          , "_notify_message_reception() is not reporting once")
        self.assertEquals(listener.received_messages[0].data[Message.ORIGINAL_BINARY_MESSAGE]
                          , "Hello world"
                          , "_notify_message_reception() is not reporting message content correctly.")
        self.assertEquals(listener.received_messages[0].data[Message.RECEIVER_PHONE_NUMBER]
                          , None
                          , "_notify_message_reception() is not reporting the receiver correctly.")
        self.assertEquals(listener.received_messages[0].data[Message.SENDER_PHONE_NUMBER]
                          , "2381280921"
                          , "_notify_message_reception() is not reporting the sender correctly.")
        self.assertEquals(listener.received_messages[0].data[Message.UDH]
                          , ""
                          , "_notify_message_reception() is not reporting the UDH correctly.")
        # Check notification of a binary message
        listener.received_messages = []
        kannel_gateway._notify_message_reception("2381280912&%06%05%04%DF%8B%00%00&%01%06%01%00%07%01%04%00%00c%A8")
        self.assertEquals(len(listener.received_messages), 1
                          , "_notify_message_reception() is reporting more than once")
        self.assertEquals(listener.received_messages[0].data[Message.ORIGINAL_BINARY_MESSAGE]
                          , "\x01\x06\x01\x00\x07\x01\x04\x00\x00\x63\xa8"
                          , "_notify_message_reception() is not reporting message content correctly.")
        print "SENDER: ", listener.received_messages[0].data[Message.SENDER_PHONE_NUMBER]
        self.assertEquals(listener.received_messages[0].data[Message.SENDER_PHONE_NUMBER]
                          , "2381280912"
                          , "_notify_message_reception() is not reporting the sender correctly.")
        self.assertEquals(listener.received_messages[0].data[Message.UDH]
                          , "\x06\x05\x04\xDF\x8B\x00\x00"
                          , "_notify_message_reception() is not reporting the UDH correctly.")

    def test_start_service(self):
        """Verifies that the KannelSMSGateway service can be started, reports
        received messages and stops on request.
        """
        kannel_gateway = KannelSMSGatewayTest.CONTEXT.get_object("kannel_sms_gateway")
        kannel_gateway.start_service()
        listener = MessageRecordingListener()
        kannel_gateway.add_sms_listener(listener)
        # Notify SMSGateway of the arrival of a message as Kannel would
        try:
            connection = urllib.urlopen("http://localhost:55055/2381280921&&Hello+world!")
            connection.close()
        except IOError:
            _LOGGER.debug("Error while opening URL to contact KannelSMSGateway.")
        # Check notification of a text message
        self.assertEquals(len(listener.received_messages), 1
                          , "_notify_message_reception() is not reporting once")
        self.assertEquals(listener.received_messages[0].data[Message.ORIGINAL_BINARY_MESSAGE]
                          , "Hello world!"
                          , "The message was not delivered correctly")
        kannel_gateway.stop_service()

if __name__ == '__main__':
    unittest.main()
